package com.itcast.activiti.cmd;

import lombok.AllArgsConstructor;
import org.activiti.engine.history.HistoricActivityInstanceQuery;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.impl.HistoricActivityInstanceQueryImpl;
import org.activiti.engine.impl.HistoricProcessInstanceQueryImpl;
import org.activiti.engine.impl.HistoricTaskInstanceQueryImpl;
import org.activiti.engine.impl.interceptor.Command;
import org.activiti.engine.impl.interceptor.CommandContext;
import org.activiti.engine.impl.persistence.entity.*;

import java.util.List;

/**
 * 更新流程实例关联的流程定义id
 *
 * @author itcast
 */
@AllArgsConstructor
public class UpdateProcessDefinitionIdCmd implements Command<Void> {
    protected String processInstanceId;
    protected String processDefinitionId;

    @Override
    public Void execute(CommandContext commandContext) {
        ExecutionEntity execution = commandContext.getExecutionEntityManager().findById(processInstanceId);
        execution.setProcessDefinitionId(processDefinitionId);
        commandContext.getExecutionEntityManager().update(execution);
        List<ExecutionEntity> childExecutionsByParentExecutionId = commandContext.getExecutionEntityManager().findChildExecutionsByParentExecutionId(execution.getId());
        for (ExecutionEntity executionEntity : childExecutionsByParentExecutionId) {
            executionEntity.setProcessDefinitionId(processDefinitionId);
            commandContext.getExecutionEntityManager().update(execution);
        }
        List<TaskEntity> tasks = commandContext.getTaskEntityManager().findTasksByProcessInstanceId(processInstanceId);
        for (TaskEntity task : tasks) {
            task.setProcessDefinitionId(processDefinitionId);
            commandContext.getTaskEntityManager().update(task);
        }

        // 修改历史Activity对应的 processDefinitionId
        HistoricActivityInstanceQuery historicActivityInstanceQuery = new HistoricActivityInstanceQueryImpl();
        historicActivityInstanceQuery.processInstanceId(processInstanceId);
        HistoricActivityInstanceEntityManager historicActivityInstanceEntityManager = commandContext.getHistoricActivityInstanceEntityManager();
        historicActivityInstanceEntityManager.deleteHistoricActivityInstancesByProcessInstanceId(processInstanceId);
        // 修改历史ProcessInstance对应的 processDefinitionId
        HistoricProcessInstanceQueryImpl historicProcessInstanceQuery = commandContext.getDbSqlSession().createHistoricProcessInstanceQuery();
        List<HistoricProcessInstance> processInstances = historicProcessInstanceQuery.processInstanceId(processInstanceId).list();
        HistoricProcessInstanceEntityManager historicProcessInstanceEntityManager = commandContext.getHistoricProcessInstanceEntityManager();
        for (HistoricProcessInstance processInstance : processInstances) {
            HistoricProcessInstanceEntityImpl historicProcessInstanceEntity = (HistoricProcessInstanceEntityImpl) processInstance;
            historicProcessInstanceEntity.setProcessDefinitionId(processDefinitionId);
            historicProcessInstanceEntityManager.update(historicProcessInstanceEntity);
        }
        // 修改历史task对应的 processDefinitionId
        HistoricTaskInstanceQueryImpl historicTaskInstanceQuery = commandContext.getDbSqlSession().createHistoricTaskInstanceQuery();
        List<HistoricTaskInstance> historicTaskInstances = historicTaskInstanceQuery.processInstanceId(processInstanceId).list();
        HistoricTaskInstanceEntityManager historicTaskInstanceEntityManager = commandContext.getHistoricTaskInstanceEntityManager();
        for (HistoricTaskInstance historicTaskInstance : historicTaskInstances) {
            HistoricTaskInstanceEntityImpl historicTaskInstanceEntity = (HistoricTaskInstanceEntityImpl) historicTaskInstance;
            historicTaskInstanceEntity.setProcessDefinitionId(processDefinitionId);
            historicTaskInstanceEntityManager.update(historicTaskInstanceEntity);
        }
//        commandContext.getHistoricActivityInstanceEntityManager().
//        List<IdentityLinkEntity> identityLinksByProcessInstanceId = commandContext.getIdentityLinkEntityManager().findIdentityLinksByProcessInstanceId(processInstanceId);
//        for (IdentityLinkEntity identityLinkEntity : identityLinksByProcessInstanceId) {
//            identityLinkEntity.setProcessDefId(processDefinitionId);
//            commandContext.getIdentityLinkEntityManager().update(identityLinkEntity);
//        }
        return null;
    }
}
